#include <string.h>
#include <WinSock2.h>
#include <Ws2tcpip.h>
#include <stdio.h>
#include <stdlib.h>
#include "Common.h"

TSocketInfo* tSocketInfo(void) {
	TSocketInfo* socketInfo = (TSocketInfo*)malloc(sizeof(TSocketInfo));
	socketInfo->buf.len = MAXBUFFSIZE;
	socketInfo->buf.buf = socketInfo->internalBuffer;
	memset(socketInfo->internalBuffer, 0, MAXBUFFSIZE);
	memset(&socketInfo->overlapped, 0, sizeof(socketInfo->overlapped));
	socketInfo->flag = 0;
	socketInfo->recvBytes = 0;
	return socketInfo;
}

TUserInfo* tUserInfo(KEYTYPE id) {
	TUserInfo* info;
	info = (TUserInfo*)malloc(sizeof(TUserInfo));
	//info = &nodePool[emptylist[emptyIdx++]];
	info->id = id;
	info->father = NULL;
	info->left = NULL;
	info->right = NULL;
	info->param = NULL;
	return info;
}
/*
void error(char *msg) {printf("%s [WSA error code: %d]\n", msg, WSAGetLastError());}

SOCKET createListenSocket(char* port, SOCKET* inSocket , bool block )
{
	struct addrinfo hints = {0};
	struct addrinfo *addrlocal = NULL;

	hints.ai_flags  = AI_PASSIVE;
	hints.ai_family = AF_INET;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = IPPROTO_TCP;

	if (getaddrinfo(NULL, port, &hints, &addrlocal) != 0)
		error("bad get addrinfo");
	if (addrlocal == NULL) error("bad get addrinfo, NULL addrlocal");

	SOCKET listenSocket;
	if (!block)
		listenSocket = WSASocket(addrlocal->ai_family, addrlocal->ai_socktype,
				addrlocal->ai_protocol, NULL, 0, WSA_FLAG_OVERLAPPED); 
	else
		listenSocket = socket(addrlocal->ai_family, addrlocal->ai_socktype, addrlocal->ai_protocol); 

	if (listenSocket == INVALID_SOCKET) error("invalid listen socket");

	if (bind(listenSocket, addrlocal->ai_addr, addrlocal->ai_addrlen) == SOCKET_ERROR)
		error("binding error");

	if (listen(listenSocket, MAXCONN) == SOCKET_ERROR)
		error("listening error");

	int nZero = 0;
	if (setsockopt(listenSocket, SOL_SOCKET, SO_SNDBUF, (char *)&nZero, sizeof(nZero)) == SOCKET_ERROR)
		error("setting option error");

	freeaddrinfo(addrlocal);

	if (inSocket != NULL) *inSocket = listenSocket;
	return listenSocket;
}

SOCKET createConnectSocket( char* port, char* ipaddr, SOCKET* inSocket  )
{
	int nRet = 0;
	struct addrinfo hints = {0};
	struct addrinfo *addr_srv = NULL;

	hints.ai_flags  = 0;
	hints.ai_family = AF_INET;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = IPPROTO_TCP;

	if (getaddrinfo(ipaddr, port, &hints, &addr_srv) != 0) 
		error("bad get addrinfo");
	if( addr_srv == NULL ) error("NULL addrinfo");

	SOCKET connectSocket;
	connectSocket = socket(addr_srv->ai_family, addr_srv->ai_socktype, addr_srv->ai_protocol);
	if( connectSocket == INVALID_SOCKET ) error("invalid socket");

	nRet = connect(connectSocket, addr_srv->ai_addr, (int) addr_srv->ai_addrlen);
	if( nRet == SOCKET_ERROR ) error("connect error");

	printf("connected\n");
	freeaddrinfo(addr_srv);

	if (inSocket != NULL) *inSocket = connectSocket;
	return connectSocket;
}
//*/
bool isLeft(TUserInfo* fa, TUserInfo* node) {
	return (fa->left!=NULL && fa->left->id == node->id);
}
bool isRight(TUserInfo* fa, TUserInfo* node) {
	return (fa->right!=NULL && fa->right->id == node->id);
}
void deleteNode(TUserInfo* node) {
// 	--emptyIdx;
// 	emptylist[emptyIdx] = (node-nodePool);
	free(node);
}

void copyNode(TUserInfo* src, TUserInfo* tar) {
	tar->id = src->id;
}

void zig(TUserInfo* root) {
	root->father->left = root->right;
	if (root->right != NULL) root->right->father = root->father;

	TUserInfo* fafa = root->father->father;
	if (fafa != NULL) {
		if (isLeft(fafa, root->father))
			fafa->left = root;
		else
			fafa->right = root;
	}
	root->father->father = root;

	root->right = root->father;
	root->father = fafa;
}

void zag(TUserInfo* root) {
	root->father->right = root->left;
	if (root->left != NULL) root->left->father = root->father;

	TUserInfo* fafa = root->father->father;
	if (fafa != NULL) {
		if (isRight(fafa, root->father))
			fafa->right = root;
		else
			fafa->left = root;
	}
	root->father->father = root;

	root->left = root->father;
	root->father = fafa;
}

void splay(TUserInfo* root, TUserInfo** rootUser) {
	while (true) {
		if (root->father == NULL)
			break;
		TUserInfo* fafa = root->father->father;

		if (fafa == NULL) {
			if (isLeft(root->father, root))
				zig(root);
			else
				zag(root);
			continue;
		}

		if (isLeft(fafa, root->father)) {
			if (isLeft(root->father, root)) {
				zig(root->father);
				zig(root);
			}
			else {
				zag(root);
				zig(root);
			}
		}
		else {
			if (isRight(root->father, root)) {
				zag(root->father);
				zag(root);
			}
			else {
				zig(root);
				zag(root);
			}
		}
	}
	*rootUser = root;
}
/*
bool addUser(TUserInfo* root, KEYTYPE id, TUserInfo** rootUser) {
	if (*rootUser == NULL) {
		*rootUser = tUserInfo(id);
		return true;
	}
	TUserInfo* newUser = tUserInfo(id);
	while (true) {
		if (id == root->id) {
			deleteNode(newUser);
			return false;
		}
		if (id < root->id) {
			if (root->left == NULL) {
				root->left = newUser;
				break;
			}
			else
				root = root->left;
		}
		else {
			if (root->right == NULL) {
				root->right = newUser;
				break;
			}
			else
				root = root->right;
		}
	}
	newUser->father = root;

// 	if (rand()%10==0)
	splay(newUser, rootUser);
	return true;
}

void deleteSingleSubtreeNode(TUserInfo* root, TUserInfo** rootUser) {
	if (root->left == NULL) {
		if (root->father == NULL)
			*rootUser = root->right;
		else {
			if (isLeft(root->father, root))
				root->father->left = root->right;
			else
				root->father->right = root->left;
		}
		if (root->right != NULL)
			root->right->father = root->father;
		deleteNode(root);
	}
	else if (root->right == NULL) {
		if (root->father == NULL)
			*rootUser = root->left;
		else {
			if (isRight(root->father, root))
				root->father->right = root->left;
			else
				root->father->left = root->right;
		}
		if (root->left != NULL)
			root->left->father = root->father;
		deleteNode(root);
	}
}

bool deleteUser(TUserInfo* root, KEYTYPE id, TUserInfo** rootUser) {
	while (true) {
		if (root == NULL) return false;
		if (root->id == id) {
			if (root->left==NULL || root->right == NULL) {
				TUserInfo* fa = root->father;
				deleteSingleSubtreeNode(root, rootUser);
				if (fa != NULL)
					splay(fa, rootUser);
				break;
			}
			TUserInfo* theMaxNode = root->left;
			while (theMaxNode->right != NULL) theMaxNode = theMaxNode->right;
			copyNode(theMaxNode, root);
			deleteSingleSubtreeNode(theMaxNode, rootUser);
			splay(root, rootUser);
			break;
		}
		if (id < root->id) root = root->left;
		else root = root->right;
	}
	return true;
}

bool find(TUserInfo* root, KEYTYPE id) {
	while (true) {
		if (root == NULL) return false;
		if (root->id == id) return true;
		if (id < root->id) root = root->left;
		else root = root->right;
	}
}
//*/
